﻿using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Net;
using System.Net.WebSockets;
using System.Text;

namespace WebSocketService.Controllers
{
    public class WebSocketController : ControllerBase
    {
        static HashSet<string> SystemHttpHeaders = new HashSet<string>() { "Connection", "Host", "Upgrade", "Sec-WebSocket-Version", "Sec-WebSocket-Key" };

        [HttpGet("/ws")]
        public async Task Get()
        {
            if (HttpContext.WebSockets.IsWebSocketRequest)
            {
                var request = HttpContext.Request;

                Console.WriteLine("连接已打开，参数字符串：" + request.QueryString.ToString());
                if (request.Headers.Count > 0)
                {
                    var skeys = request.Headers.Keys;
                    foreach (var skey in skeys)
                    {
                        if (!SystemHttpHeaders.Contains(skey))
                            Console.WriteLine($"http头：{skey} = {request.Headers[skey]}");
                    }


                }
                using WebSocket webSocket = await
                                   HttpContext.WebSockets.AcceptWebSocketAsync();
                await Echo(HttpContext, webSocket);
            }
            else
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
        }

        private async Task Echo(HttpContext context, WebSocket webSocket)
        {
            try
            {
                var buffer = new byte[1024 * 4];
                List<byte> bData = new List<byte>();
                WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                while (!result.CloseStatus.HasValue)
                {

                    if (result.EndOfMessage)
                    {
                        string bStr;
                        if (bData.Count > 0)
                        {
                            bStr = Encoding.UTF8.GetString(bData.ToArray());
                        }
                        else
                        {
                            bStr = Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count));
                        }

                        Console.WriteLine(bStr);
                        try
                        {
                            var jobj = JObject.Parse(bStr);
                            if (jobj.ContainsKey("cmd"))
                            {
                                var cmd = jobj["cmd"]?.ToString();
                                string sResult;
                                if (cmd == "GetWorkParameter")
                                {
                                    sResult= System.IO.File.ReadAllText("web_j.json");
                                }
                                else
                                {
                                    sResult = "{\"reply\":\"" + cmd + "\",\"result\":1}";
                                }
                                var buf = Encoding.UTF8.GetBytes(sResult);
                                await webSocket.SendAsync(new ArraySegment<byte>(buf, 0, buf.Length), result.MessageType, result.EndOfMessage, CancellationToken.None);
                            }
                            Console.WriteLine("收到字节:" + result.Count.ToString());
                        }
                        catch
                        {


                        }
                        bData.Clear();
                    }
                    else
                    {
                        bData.AddRange(new ArraySegment<byte>(buffer, 0, result.Count));
                    }
                    result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                }
                await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
            }
            catch (Exception ex)
            {

                Console.WriteLine("连接发生错误:" + ex.Message);
            }

            Console.WriteLine("连接已断开");
        }
    }
}
